#include "ConfigFile.h"

#include "rapidjson/document.h"
using namespace rapidjson;

namespace movesense {

ConfigFile::ConfigFile( vector<CameraInfo> scanList )
{
	//map
	name2mode["LR"] = CAMERA_LR;
	name2mode["LD"] = CAMERA_LD;
	name2mode["LRD"]   = CAMERA_LRD;
	name2mode["LR_HD"] = CAMERA_LR_HD;
	name2mode["LD_HD"] = CAMERA_LD_HD;
	name2mode["LRD_HD"] = CAMERA_LRD_HD;

	cameraList = scanList;

	bool res = GetCameraInfo("./ConfigFiles/CameraID.json");
	if (res == false)
	{
		cout << "json parse fail!" << endl;
	}

	vector<CameraInfo>::iterator ite = cameraList.begin();
	vector<CameraInfo>::iterator dest = ite;

	for (; ite != cameraList.end(); ++ite)
	{
		CameraInfo *cameraInfo = &(*ite);

		int index;
		for (index = 0; index<jsonList.size(); index++)
		{
			if (cameraInfo->vid == jsonList[index].vid && cameraInfo->pid == jsonList[index].pid)
			{
				cameraInfo->name = jsonList[index].name;
				cameraInfo->protocol = jsonList[index].protocol;
				cameraInfo->parseProtocol = jsonList[index].parseProtocol;
				GetCameraSetting(cameraInfo);
				*dest++ = *ite;
			}
		}

	}

	cameraList.erase(dest, cameraList.end());

}

bool ConfigFile::GetCameraInfo(string idFile)
{
	string file = ReadJsonFile(idFile);

	Document doc;
	if (doc.Parse(file.c_str()).HasParseError())
	{
		return false;
	}

	if (!doc.HasMember("camera_id"))
	{
		return false;
	}

	Value &v = doc["camera_id"];
	if (!v.IsArray())
	{
		return false;
	}

	CameraInfo cameraInfo;
	for (int i=0; i<v.Size(); i++)
	{
		cameraInfo.name = v[i]["name"].GetString();
		cameraInfo.protocol = v[i]["protocol"].GetString();
		cameraInfo.parseProtocol = v[i]["parse_protocol"].GetString();
		cameraInfo.vid = v[i]["vid"].GetString();
		cameraInfo.pid = v[i]["pid"].GetString();

		jsonList.push_back(cameraInfo);
	}

	return true;
}

bool ConfigFile::GetCameraSetting(CameraInfo *info)
{
	string setFile = "./ConfigFiles/"+info->name+".json";
	string file = ReadJsonFile(setFile);

	Document doc;
	if (doc.Parse(file.c_str()).HasParseError())
	{
		return false;
	}

	if (!doc.HasMember("default") || 
		!doc.HasMember("resolution") || 
		!doc.HasMember("framerate") ||
		!doc.HasMember("mode"))
	{
		return false;
	}

	//default
	Value &v = doc["default"];
	info->setting.resolution.width = v["resolution"]["w"].GetInt();
	info->setting.resolution.height = v["resolution"]["h"].GetInt();
	info->setting.framerate = v["framerate"].GetInt();
	info->setting.mode = name2mode[v["mode"].GetString()];

	info->setting.disparity.type = 96;
	info->setting.disparity.bpp = 8;

	//resolution
	v = doc["resolution"];
	if (!v.IsArray())
	{
		return false;
	}

	for (int i=0; i<v.Size(); i++)
	{
		Resolution res;
		res.width = v[i]["w"].GetInt();
		res.height = v[i]["h"].GetInt();
		info->setting.resolutionList.push_back(res);
	}

	//framerate
	v = doc["framerate"];
	if (!v.IsArray())
	{
		return false;
	}

	for (int i=0; i<v.Size(); i++)
	{
		int framerate = v[i].GetInt();
		info->setting.framerateList.push_back(framerate);
	}

	//mode
	v = doc["mode"];
	if (!v.IsArray())
	{
		return false;
	}

	for (int i=0; i<v.Size(); i++)
	{
		int mode = name2mode[v[i].GetString()];
		info->setting.modeList.push_back(mode);
	}

	//disparity
	if (doc.HasMember("disparity"))
	{
		v = doc["disparity"];
		info->setting.disparity.type = v["type"].GetInt();
		info->setting.disparity.bpp = v["bpp"].GetInt();
	}

	return true;
}
	

string ConfigFile::ReadJsonFile(string filename)
{
	ifstream in(filename.c_str());

	string stringFromStream;
	string line;
	while (getline(in, line)) 
	{
		stringFromStream.append(line + "\n");
	}
	in.close();

	return stringFromStream;
}


}
